﻿<script setup lang="ts" name="FolderMove">
import { FolderApi } from '@/api/infra/file'
import { getTreeExpandNodeParents } from '../utils'

const { success } = useMessage()
const emit = defineEmits(['save', 'close'])

const props = defineProps({
  folderList: { type: Array as any }
})

const treeRef: any = ref(null)

const initInfo: any = ref({
  dialogVisible: false,
  treeList: [],
  defaultExpandNodes: [],
  disabledSelectedNode: [],
  selectedNode: [],
  moveFolderId: 0
})

watch(
  () => props.folderList,
  (val) => {
    initInfo.value.treeList = val
  },
  {
    deep: true,
    immediate: true
  }
)

// 显示弹窗
const showDialog = (v) => {
  console.log(v, '文件夹移动')
  initInfo.value.dialogVisible = true
  resetTreeList()
  initInfo.value.selectedNode = v
  nextTick(() => {
    treeRef.value.setCheckedKeys([v[0].folder_id], false)
  })
  const selectedNodeSearch = (data, id) => {
    data.forEach(item => {
      item.disabled = false
      if (item.id === id) {
        item.disabled = true
        initInfo.value.disabledSelectedNode.push(item.id)
        if (item.children.length > 0) {
          disabledChildrenNode(item.children)
        }
      } else {
        if (!item.disabled && item.children.length > 0) {
          selectedNodeSearch(item.children, id)
        }
      }
    })
  }
  const disabledChildrenNode = (data) => {
    data.forEach(item => {
      item.disabled = true
      initInfo.value.disabledSelectedNode.push(item.id)
      if (item.children.length > 0) {
        disabledChildrenNode(item.children)
      }
    })
  }
  initInfo.value.selectedNode.forEach(k => {
    if (k.isFolder) {
      selectedNodeSearch(initInfo.value.treeList, k.id)
    }
  })
  initInfo.value.defaultExpandNodes = getTreeExpandNodeParents(initInfo.value.treeList, v[0].folder_id)
}

// 子组件将方法暴露给父组件
defineExpose({ showDialog })

// 禁止选择的文件夹添加禁用样式
const disabledNodeClass = (data) => {
  if (initInfo.value.disabledSelectedNode.includes(data.id)) {
    return 'disabled'
  } else {
    return ''
  }
}

// 重置移动相关参数数据
const resetTreeList = () => {
  initInfo.value.moveFolderId = 0
  initInfo.value.disabledSelectedNode = []
  initInfo.value.selectedNode = []
  setTreeDisabled(initInfo.value.treeList)
}

// 递归处理禁用状态
const setTreeDisabled = (data) => {
  data.forEach(item => {
    item.disabled = false
    if (item.children.length > 0) {
      setTreeDisabled(item.children)
    }
  })
}

// 关闭弹窗
const closeDialog = () => {
  initInfo.value.dialogVisible = false
  emit('close')
}

// 文件夹点击事件
const handleNodeClick = (v) => {
  if (!initInfo.value.disabledSelectedNode.includes(v.id)) {
    initInfo.value.moveFolderId = v.id
    treeRef.value.setCheckedKeys([v.id], false)
  } else {
    const checkedKeys = treeRef.value.getCheckedKeys()
    const index = checkedKeys.findIndex((item) => item === v.id)
    index !== -1 && checkedKeys.splice(index, 1)
    treeRef.value.setCheckedKeys(checkedKeys, false)
  }
}

// 保存
const handleOk = () => {
  if (initInfo.value.selectedNode[0].folder_id === initInfo.value.moveFolderId) {
    closeDialog()
    return false
  }
  const folder_ids: any = []
  const attachment_ids: any = []
  initInfo.value.selectedNode.forEach(item => {
    if (item.isFolder) {
      folder_ids.push(item.id)
    } else {
      attachment_ids.push(item.id)
    }
  })
  FolderApi.move({ folder_ids: folder_ids, attachment_ids: attachment_ids, folder_id: initInfo.value.moveFolderId }).then((res: any) => {
    if (res.code === 200) {
      success('文件已移动成功！')
      emit('save')
      closeDialog()
    }
  })
}
</script>

<template>
  <ElDialog v-model="initInfo.dialogVisible" title="移动到" width="700px" align-center @close="closeDialog">
    <div class="folder-list">
      <ElScrollbar>
        <ElTree
          ref="treeRef"
          class="tree-level"
          :data="initInfo.treeList"
          :props="{ label: 'title', disabled: 'disabled', class: disabledNodeClass }"
          node-key="id"
          :expand-on-click-node="false"
          :check-on-click-node="true"
          auto-expand-parent
          :default-expanded-keys="initInfo.defaultExpandNodes"
          check-strictly
          @node-click="handleNodeClick">
          <template #default="{ node, data }">
            <span class="item-tree-node">
              <span>{{ node.label }}</span>
              <template v-for="item in data.level">
                <span v-if="!data.hideLine.includes(item)" :key="item.value" :class="['item-tree-node-line-vertical', data.isLast && item == data.level ? 'is-last' : '', data.isFirst && data.level === 1 ? 'is-first' : '']" :style="{ left: 18 * (item - 1) + 12 + 'px' }" />
              </template>
              <span class="item-tree-node-line-horizontal" :style="{ left: 18 * (data.level - 1) + 12 + 'px' }" />
            </span>
          </template>
        </ElTree>
      </ElScrollbar>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <ElButton @click="closeDialog">取消</ElButton>
        <ElButton type="primary" @click="handleOk">确定</ElButton>
      </span>
    </template>
  </ElDialog>
</template>

<style scoped lang="scss">
.folder-list {
  position: relative;
  height: 260px;
  border: 1px solid var(--el-border-color);
  border-radius: 2px;

  .el-scrollbar {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

    :deep(.el-scrollbar__wrap) {
      padding: calc(var(--el-space) / 2);
    }
  }
}

.el-input {
  :deep(.el-input__icon) {
    cursor: pointer;
  }
}

.tree-level {
  :deep(.el-tree-node.is-checked) {
    >.el-tree-node__content {
      font-weight: bold;
      color: var(--el-color-primary);
      background-color: var(--el-color-primary-light-9);
    }
  }
}
</style>
